'use strict';

var fs = require('fs');

//require our websocket library 
var WebSocketServer = require('ws').Server; 

  var cfg = {
    ssl: true,
    port: 9090,
    ssl_key: '/home/luyao/ssl/domain.key',
    ssl_cert: '/home/luyao/ssl/chained.pem'
  };

  var httpServ = (cfg.ssl) ? require('https') : require('http');

  var WebSocketServer = require('ws').Server;

  var app = null;

    // dummy request processing
  var processRequest = function (req, res) {
    res.writeHead(200);
    res.end('All glory to WebSockets!\n');
  };

  if (cfg.ssl) {
    app = httpServ.createServer({

            // providing server with  SSL key/cert
      key: fs.readFileSync(cfg.ssl_key),
      cert: fs.readFileSync(cfg.ssl_cert)

    }, processRequest).listen(cfg.port);
  } else {
    app = httpServ.createServer(processRequest).listen(cfg.port);
  }

//creating a websocket server at port 9090 
var wss = new WebSocketServer({server: app});

//all connected to the server users 
var users = {};

//when a user connects to our sever 
wss.on('connection', function(connection) {
    console.log("User connected");
    
    //when server gets a message from a connected user 
    connection.on('message', function(message) { 
	var data; 
	try { 
            data = JSON.parse(message); 
	} catch (e) { 
            console.log("Invalid JSON"); 
            data = {}; 
	}
	
	//switching type of the user message 
	switch (data.type) { 
            //when a user tries to login
        case "login": 
            console.log("User logged", data.name); 
	    
            //if anyone is logged in with this username then refuse 
            if(users[data.name]) { 
		sendTo(connection, {type: "login", success: false}); 
            } else { 
		//save user connection on the server 
		users[data.name] = connection; 
		connection.name = data.name; 
		
		sendTo(connection, {type: "login", success: true}); 
            } 
            break;
	    
        case "offer": 
            //for ex. UserA wants to call UserB 
            console.log("Sending offer to: ", data.name);
	    
            //if UserB exists then send him offer details 
            var conn = users[data.name]; 
            if(conn != null) { 
		//setting that UserA connected with UserB 
		connection.otherName = data.name; 
		sendTo(conn, {type: "offer", payload: data.offer, from: connection.name}); 
            }
            break;
	    
        case "answer": 
            console.log("Sending answer to: ", data.name); 
            //for ex. UserB answers UserA 
            var conn = users[data.name]; 
            if(conn != null) { 
		connection.otherName = data.name; 
		sendTo(conn, {type: "answer", payload: data.answer, from: connection.name}); 
            } 
            break; 
	    
        case "candidate": 
            console.log("Sending candidate to:",data.name); 
            var conn = users[data.name];
            if(conn != null) { 
		sendTo(conn, {type: "candidate", payload: data.candidate, from: connection.name}); 
            } 
            break;
	    
        case "leave": 
            console.log("Disconnecting from", data.name); 
            var conn = users[data.name];
	    if(conn){
		conn.otherName = null; 
		//notify the other user so he can disconnect his peer connection 
		sendTo(conn, {type: "leave"}); 
	    }
            break;
	    
        default: 
            sendTo(connection, {type: "error", payload: "Command not found: " + data.type}); 
            break; 
	}
    }); 
    
    //when user exits, for example closes a browser window 
    //this may help if we are still in "offer","answer" or "candidate" state 
    connection.on("close", function() { 
	if(connection.name) { 
            delete users[connection.name]; 
            if(connection.otherName) { 
		console.log("Disconnecting from ", connection.otherName); 
		var conn = users[connection.otherName]; 
		if(conn) {
		    conn.otherName = null;
		    sendTo(conn, {type: "leave"}); 
		}
            }
	}
    });

});

function sendTo(connection, message) { 
    connection.send(JSON.stringify(message)); 
}
